﻿using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using SmartAgricultureService.Core;
using SmartAgricultureService.Core.Mqtt;
using SmartAgricultureService.Models;
using SmartAgricultureService.Models.Enums;
using SmartAgricultureService.Models.Tables;
using SmartAgricultureService.Tables;

namespace SmartAgricultureService.Controllers
{
    [Authorize]
    [ApiController]
    [Route("api/[controller]")]
    public class SyncController(DatabaseContext database, IHttpContextAccessor httpContextAccessor) : ControllerBase(httpContextAccessor)
    {
        [HttpPost("uploadData")]
        public async Task<IActionResult> UploadData([FromBody] IEnumerable<UploadInfo> uploads)
        {
            try
            {
                var array = new List<UploadEntry>();
                foreach (var upload in uploads)
                {
                    if (!string.IsNullOrEmpty(upload.DeviceId))
                    {
                        var deviceEntry = await database.Devices.Include(o => o.Area).AsNoTracking().FirstOrDefaultAsync(x => x.Id == upload.DeviceId && !x.Delete && x.Active);
                        if (deviceEntry != null)
                        {
                            array.Add(new UploadEntry
                            {
                                Id = Guid.NewGuid().ToString("N"),
                                CreateDate = upload.CreateDate,
                                DeviceId = upload.DeviceId,
                                Humidity = upload.Humidity,
                                Illumination = upload.Illumination,
                                Temperature = upload.Temperature
                            });
                        }
                    }
                }
                if (array.Count > 0)
                {
                    await database.Uploads.AddRangeAsync(array);
                    await database.SaveChangesAsync();
                    return Success("保存成功！");
                }
                return Success("无效的参数");
            }
            catch (Exception ex)
            {
                return Error(ex);
            }
        }
        [HttpGet("getData")]
        public async Task<IActionResult> GetData(string areaCode, string deviceId)
        {
            try
            {
                if (!string.IsNullOrEmpty(deviceId))
                {
                    var deviceEntry = await database.Devices.Include(o => o.Area).AsNoTracking().FirstOrDefaultAsync(x => x.Id == deviceId && !x.Delete && x.Active);
                    if (deviceEntry == null)
                        return Reject("不存在该设备");
                    else if (!await database.IsMatchArea(deviceEntry.Area.Code))
                        return Reject("设备不在指定的区域内，无法获取！");
                    else
                    {
                        var mqtt = MqttData.Create(deviceEntry.Area.Code, deviceId, new MqttDataDetail { Type = MqttType.Data });
                        await MqttService.PublishData(mqtt);
                        return Success($"请求设备成功");
                    }
                }
                else if (!string.IsNullOrEmpty(areaCode))
                {
                    var areaEntry = await database.Areas.AsNoTracking().FirstOrDefaultAsync(x => x.Code == areaCode && !x.Delete && x.Active);
                    if (!await database.IsMatchArea(areaCode))
                        return Reject("设备不在指定的区域内，无法获取！");
                    else if (areaEntry != null)
                    {
                        var mqtt = MqttData.Create(areaEntry.Code, new MqttDataDetail { Type = MqttType.Data });
                        await MqttService.PublishData(mqtt);
                        return Success($"请求设备成功");
                    }
                    else
                        return Reject("不存在该区域");
                }
                return Success("无效的参数");
            }
            catch (Exception ex)
            {
                return Error(ex);
            }
        }
        [HttpPost("irrigateNow")]
        public async Task<IActionResult> IrrigateNow([FromBody] SyncInfo syncInfo)
        {
            try
            {
                if (!string.IsNullOrEmpty(syncInfo.DeviceId))
                {
                    var deviceEntry = await database.Devices.Include(o => o.Area).AsNoTracking().FirstOrDefaultAsync(x => x.Id == syncInfo.DeviceId && !x.Delete && x.Active);
                    if (deviceEntry == null)
                        return Reject("不存在该设备");
                    else if (!await database.IsMatchArea(deviceEntry.Area.Code))
                        return Reject("设备不在指定的区域内，无法获取！");
                    else
                    {
                        var mqtt = MqttData.Create(deviceEntry.Area.Code, syncInfo.DeviceId, new MqttDataDetail { Type = MqttType.Irrigate });
                        await MqttService.PublishData(mqtt);
                        return Success("请求设备成功");
                    }
                }
                else if (!string.IsNullOrEmpty(syncInfo.AreaCode))
                {
                    var areaEntry = await database.Areas.AsNoTracking().FirstOrDefaultAsync(x => x.Code == syncInfo.AreaCode && !x.Delete && x.Active);
                    if (!await database.IsMatchArea(syncInfo.AreaCode))
                        return Reject("设备不在指定的区域内，无法获取！");
                    else if (areaEntry != null)
                    {
                        var mqtt = MqttData.Create(areaEntry.Code, new MqttDataDetail { Type = MqttType.Irrigate });
                        await MqttService.PublishData(mqtt);
                        return Success($"请求设备成功");
                    }
                    else
                        return Reject("不存在该区域");
                }
                return Success("无效的参数");
            }
            catch (Exception ex)
            {
                return Error(ex);
            }
        }
        [HttpPost("irrigateStop")]
        public async Task<IActionResult> IrrigateStop([FromBody] SyncInfo syncInfo)
        {
            try
            {
                if (!string.IsNullOrEmpty(syncInfo.DeviceId))
                {
                    var deviceEntry = await database.Devices.Include(o => o.Area).AsNoTracking().FirstOrDefaultAsync(x => x.Id == syncInfo.DeviceId && !x.Delete && x.Active);
                    if (deviceEntry == null)
                        return Reject("不存在该设备");
                    if (!await database.IsMatchArea(deviceEntry.Area.Code))
                        return Reject("设备不在指定的区域内，无法获取！");
                    else
                    {
                        var mqtt = MqttData.Create(deviceEntry.Area.Code, syncInfo.DeviceId, new MqttDataDetail { Type = MqttType.IrrigateStop });
                        await MqttService.PublishData(mqtt);
                        return Success($"请求设备成功");
                    }
                }
                else if (!string.IsNullOrEmpty(syncInfo.AreaCode))
                {
                    var areaEntry = await database.Areas.AsNoTracking().FirstOrDefaultAsync(x => x.Code == syncInfo.AreaCode && !x.Delete && x.Active);
                    if (!await database.IsMatchArea(syncInfo.AreaCode))
                        return Reject("设备不在指定的区域内，无法获取！");
                    else if (areaEntry != null)
                    {
                        var mqtt = MqttData.Create(areaEntry.Code, new MqttDataDetail { Type = MqttType.Irrigate });
                        await MqttService.PublishData(mqtt);
                        return Success($"请求设备成功");
                    }
                    else
                        return Reject("不存在该区域");
                }
                return Success("无效的参数");
            }
            catch (Exception ex)
            {
                return Error(ex);
            }
        }
        [HttpPost("irrigateInterval")]
        public async Task<IActionResult> IrrigateInterval([FromBody] SyncInfo syncInfo)
        {
            try
            {
                if (!string.IsNullOrEmpty(syncInfo.DeviceId))
                {
                    var deviceEntry = await database.Devices.Include(o => o.Area).AsNoTracking().FirstOrDefaultAsync(x => x.Id == syncInfo.DeviceId && !x.Delete && x.Active);
                    if (deviceEntry == null)
                        return Reject("不存在该设备");
                    else if (!await database.IsMatchArea(deviceEntry.Area.Code))
                        return Reject("设备不在指定的区域内，无法获取！");
                    else
                    {
                        var mqtt = MqttData.Create(deviceEntry.Area.Code, syncInfo.DeviceId, new MqttDataDetail
                        {
                            Interval = syncInfo.Interval,
                            Type = MqttType.IrrigateInterval
                        });
                        await MqttService.PublishData(mqtt);
                        return Success($"请求设备成功");
                    }
                }
                else if (!string.IsNullOrEmpty(syncInfo.AreaCode))
                {
                    var areaEntry = await database.Areas.AsNoTracking().FirstOrDefaultAsync(x => x.Code == syncInfo.AreaCode && !x.Delete && x.Active);
                    if (!await database.IsMatchArea(syncInfo.AreaCode))
                        return Reject("设备不在指定的区域内，无法获取！");
                    else if (areaEntry != null)
                    {
                        var mqtt = MqttData.Create(areaEntry.Code, new MqttDataDetail
                        {
                            Interval = syncInfo.Interval,
                            Type = MqttType.IrrigateInterval
                        });
                        await MqttService.PublishData(mqtt);
                        return Success($"请求设备成功");
                    }
                    else
                        return Reject("不存在该区域");
                }
                return Success("无效的参数");
            }
            catch (Exception ex)
            {
                return Error(ex);
            }
        }
        [HttpPost("irrigateThreshold")]
        public async Task<IActionResult> IrrigateThreshold([FromBody] SyncInfo syncInfo)
        {
            try
            {
                if (!string.IsNullOrEmpty(syncInfo.DeviceId))
                {
                    var deviceEntry = await database.Devices.Include(o => o.Area).AsNoTracking().FirstOrDefaultAsync(x => x.Id == syncInfo.DeviceId && !x.Delete && x.Active);
                    if (deviceEntry == null)
                        return Reject("不存在该设备");
                    if (!await database.IsMatchArea(deviceEntry.Area.Code))
                        return Reject("设备不在指定的区域内，无法获取！");
                    else
                    {
                        var mqtt = MqttData.Create(deviceEntry.Area.Code, syncInfo.DeviceId, new MqttDataDetail
                        {
                            Type = MqttType.IrrigateThreshold,
                            Threshold = syncInfo.Threshold
                        });
                        await MqttService.PublishData(mqtt);
                        return Success($"请求设备成功");
                    }
                }
                else if (!string.IsNullOrEmpty(syncInfo.AreaCode))
                {
                    var areaEntry = await database.Areas.AsNoTracking().FirstOrDefaultAsync(x => x.Code == syncInfo.AreaCode && !x.Delete && x.Active);
                    if (!await database.IsMatchArea(syncInfo.AreaCode))
                        return Reject("设备不在指定的区域内，无法获取！");
                    else if (areaEntry != null)
                    {
                        var mqtt = MqttData.Create(areaEntry.Code, new MqttDataDetail
                        {
                            Type = MqttType.IrrigateThreshold,
                            Threshold = syncInfo.Threshold
                        });
                        await MqttService.PublishData(mqtt);
                        return Success($"请求设备成功");
                    }
                    else
                        return Reject("不存在该区域");
                }
                return Success("无效的参数");
            }
            catch (Exception ex)
            {
                return Error(ex);
            }
        }
        [HttpPost("reportData")]
        public async Task<IActionResult> ReportData([FromBody] List<UploadInfo> uploadInfos)
        {
            try
            {
                if (uploadInfos != null)
                {
                    var uploadEntries = uploadInfos.Select(info => new UploadEntry
                    {
                        DeviceId = info.DeviceId,
                        Humidity = info.Humidity,
                        CreateDate = info.CreateDate,
                        Illumination = info.Illumination,
                        Temperature = info.Temperature,
                        Id = Guid.NewGuid().ToString("N")
                    });
                    await database.Uploads.AddRangeAsync(uploadEntries);
                    await database.SaveChangesAsync();
                }
                return Success("上传成功！");
            }
            catch (Exception ex)
            {
                return Error(ex);
            }
        }
    }
}